import re

from pod.macros.html.util import tag
from pod.std import *
from format import *
from structure import *
from table import *
from style import processStyle
from control import *

class DocumentFactory(object):
    registry = {}
    
    def __init__(self):
        pass
        
    def __call__(self, ctx, type):
        return self.registry[type](ctx)
        
    @classmethod
    def register(cls, name, doc):
        cls.registry[name] = doc
        
Macro.register("all", "doc", DocumentFactory())
        
class DocumentType(type):
    def __init__(self, name, bases, dct):
        super(DocumentType, self).__init__(name, bases, dct)
        id = getattr(self, "name", name)
        DocumentFactory.register(id, self)
                 
class Document(object):
    __metaclass__ = DocumentType
    
    def __init__(self):
        super(Document, self).__init__()
                            
class HTMLDocument(Document):
    name = "html"
    
    def __init__(self, ctx, width="100%"):
        super(HTMLDocument, self).__init__()
        self.ctx = ctx
        
        self.ctx.env["doctype"] = "html"
        self.ctx.env["doc.width"] = width
        if not "doc.preamble" in self.ctx.env:
            self.ctx.env["doc.preamble"] = []
        
        # set up some decent defaults
        self.ctx.env["doc.css"] = {}
        css(self.ctx.env, "table.default", border="0px solid black", padding="3px", border_collapse="collapse")
        css(self.ctx.env, "tr.default", border="0px solid black", padding="3px")
        css(self.ctx.env, "td.default", border="0px solid black", padding="3px")

        css(self.ctx.env, "table.figure", border="1px solid black", padding="3px", border_collapse="collapse")
        css(self.ctx.env, "tr.figure", border="1px solid black", padding="3px")
        css(self.ctx.env, "td.figure", border="1px solid black", padding="3px")
        css(self.ctx.env, "td.figure_caption", border="1px solid black", padding="3px", background_color="#eeeeee")

        css(self.ctx.env, "table.equation", border="0px solid black", width="100%")
        css(self.ctx.env, "tr.equation", border="0px solid black", width="100%")
        css(self.ctx.env, "td.equation", border="0px solid black", width="100%")
        css(self.ctx.env, "td.equation_number", border="0px solid black", width="100%", text_align="right")
        css(self.ctx.env, ".inline_equation", vertical_align="middle")
        
    def __call__(self, content):
        preamble = "\n".join(self.ctx.env["doc.preamble"])

        style = tag("style", type="text/css")
        for name, entry in self.ctx.env["doc.css"].items():
            settings = ["%s:%s;" % (key, value) for key, value in entry.items()]
            style += "\t%s {%s}\n" % (name, " ".join(settings))

        doc = tag("html")[
            tag("head")[preamble, style],            
            tag("body", style="width:%s;" % self.ctx.env["doc.width"])[Macro.flatten(content)]
        ]
        
        return doc

class SetEnv(Macro):
    name = "setenv"
    
    def __init__(self, ctx, key, value):
        super(SetEnv, self).__init__()
        ctx.env[key] = value        

class Ref(Macro):
    """
    Example:
    As you will see in figure #ref(label="label"), ..
    """
    name = "ref"
    doctype = "html"

    def __init__(self, ctx, ref):
        super(Ref, self).__init__()
        self.ref = ref
        self.ctx = ctx

    def __call__(self, content):
        return str(self.ctx.env["label:%s" % self.ref].number)

class Style(Macro):
    name = "style"
    
    def __init__(self, ctx, filename):
        super(Style, self).__init__()
        with open(filename, "r") as input:
            style = processStyle("".join(input.readlines()))
            
            for key, value in style.items():
                ctx.env["style:%s" % key] = value
        #endwith

class Set(Macro):
    """
    Two uses for set:
    set(var=value)
    
    or (for lists and dicts)
    
    set(var, value, index)
    """
    name = "set"
    
    def __init__(self, ctx, *args, **kwargs):
        if len(args) == 3:
            var, value, index = args
            ctx.getVar(var, None)[index] = value
        else:            
            for var, value in kwargs.items():
                ctx.setVar(var, value)
        #endif
